/**
 *  学习目标：Todos 案例
    需求
      1. ✅拆分组件-拆成函数式组件
      2. ✅列表数据定义，及渲染
      3. ✅根据id删除一条数据
      4. ✅根据id更新一条数据的状态
      5. ✅清除已完成
      6. ✅统计剩余任务
      7. ✅点谁谁高亮
      8. ✅切换数据
      9. ✅新增数据
      10. ✅小选影响全选
      11. ✅全选影响小选
      
 */
import React, { useState } from 'react';
import './styles/base.css';
import './styles/index.css';

export default function App() {
  // 2.1. 声明数据
  const [list, setList] = useState([
    {
      id: 1,
      task: '学习React',
      isDone: false,
    },
    {
      id: 2,
      task: '学习Vue3',
      isDone: true,
    },
    {
      id: 3,
      task: '学习TS',
      isDone: false,
    },
  ]);

  // 7.1 声明状态type - 状态提升
  const [type, setType] = useState('all');

  // 4.1 声明修改list中一条数据状态的方法
  const handleUpdateById = (id) => {
    // 完成更新的逻辑
    const newList = list.map((item) => ({
      ...item,
      isDone: item.id === id ? !item.isDone : item.isDone,
    }));
    setList(newList);
  };

  // 3.1 声明删除方法
  const handleDelById = (id) => {
    // 3.4 删除数据
    setList(list.filter((item) => item.id !== id));
  };

  // 5.1 声明清除方法
  const handleClear = () => {
    const newList = list.filter((item) => !item.isDone);
    setList(newList);
  };

  // 6.1 定义计算属性 restCount
  const restCount = list.filter((item) => !item.isDone).length;

  // 8.1 定义一个计算属性
  const showList = list.filter((item) => {
    // 如果type为all，返回值是true
    if (type === 'all') return true;
    // 如果type为active， 返回item.isDone为false
    if (type === 'active') return !item.isDone;
    // 如果type为completed，返回item.isDone
    return item.isDone;
  });

  // 9.2 在App中，定义一个新增的方法
  const handleAdd = (task) => {
    // 新增的逻辑
    setList([
      {
        id: Date.now(),
        task,
        isDone: false,
      },
      ...list,
    ]);
  };

  // 10.1 计算属性-计算list中每项元素的isDOne是否true 💥 注意数组为空，every默认返回true
  const isAll = list.length ? list.every((item) => item.isDone) : false;
  // 11.1 定义覆盖小选矿isDone的方法
  const handleCheckAll = (checked) => {
    // 11.4 同步小选矿的isDone属性为checked
    setList(list.map((item) => ({ ...item, isDone: checked })));
  };

  return (
    <section className="todoapp">
      {/* 头部 */}
      {/* 9.3 父传子回调函数handleAdd */}
      <Header handleAdd={handleAdd}></Header>
      {/* 主体 */}
      {/* 2.2 父传子技术 */}
      {/* 3.2 父传子回调函数 */}
      <Main
        // 8.2 替换掉原本的list
        list={showList}
        handleDelById={handleDelById}
        handleUpdateById={handleUpdateById}
        // 10.2 将isAll传给Main组件
        isAll={isAll}
        // 11.2 父传子
        handleCheckAll={handleCheckAll}
      ></Main>
      {/* 底部 */}
      {/* 5.2 父传子传回调 */}
      {/* 6.2 传给Footer组件，显示 */}
      {/* 7.2 父传子给Footer */}
      <Footer
        setType={setType}
        handleClear={handleClear}
        restCount={restCount}
        type={type}
      ></Footer>
    </section>
  );
}
function Footer({ handleClear, restCount, type, setType }) {
  return (
    <footer className="footer">
      <span className="todo-count">
        <strong>{restCount}</strong> 剩余
      </span>
      <ul className="filters">
        <li>
          {/* 7.3 使用排他判断，让多个表达式的判断条件使用同一个变量 */}
          {/* 7.4 点击修改type的值 */}
          {/* 7.5 onClick调用父传子的回调函数，setType */}
          <a onClick={() => setType('all')} className={type === 'all' ? 'selected' : ''} href="#/">
            全部
          </a>
        </li>
        <li>
          <a
            onClick={() => setType('active')}
            className={type === 'active' ? 'selected' : ''}
            href="#/active"
          >
            未完成
          </a>
        </li>
        <li>
          <a
            onClick={() => setType('completed')}
            className={type === 'completed' ? 'selected' : ''}
            href="#/completed"
          >
            已完成
          </a>
        </li>
      </ul>
      {/* 5.3 绑定事件 */}
      <button className="clear-completed" onClick={handleClear}>
        清除已完成
      </button>
    </footer>
  );
}

function Main({ list, handleDelById, handleUpdateById, isAll, handleCheckAll }) {
  return (
    <section className="main">
      {/* 10.3 isAll绑定checked属性 */}
      <input
        id="toggle-all"
        className="toggle-all"
        type="checkbox"
        checked={isAll}
        onChange={(e) => handleCheckAll(e.target.checked)}
      />
      <label htmlFor="toggle-all">全选</label>
      <ul className="todo-list">
        {/* 2.3 列表渲染 */}
        {list.map((item) => {
          return (
            <li key={item.id} className={item.isDone ? 'completed' : ''}>
              <div className="view">
                <input
                  className="toggle"
                  type="checkbox"
                  checked={item.isDone}
                  // 4.3 绑定给onChange事件
                  onChange={() => handleUpdateById(item.id)}
                />
                <label>{item.task}</label>
                {/* 3.3 绑定事件，注意传参id */}
                <button className="destroy" onClick={() => handleDelById(item.id)}></button>
              </div>
            </li>
          );
        })}
      </ul>
    </section>
  );
}

function Header({ handleAdd }) {
  // 9.1 Header改造为受控组件
  const [task, setTask] = useState('');

  // 9.4 监听回车事件
  const handleKeyDown = (e) => {
    // 如果为空则提示不能为空，并且阻止向下执行

    if (e.keyCode === 13) {
      // 9.5 非空判断
      if (!e.target.value.trim()) {
        return alert('任务不能为空');
      }
      // 新增数据
      handleAdd(task);
      // 清空数据
      setTask('');
    }

    // 9.6 监听ESc清空数据
    if (e.keyCode === 27) {
      setTask('');
    }
  };

  return (
    <header className="header">
      <h1>todos</h1>
      <input
        className="new-todo"
        placeholder="需要做什么"
        value={task}
        onChange={(e) => setTask(e.target.value)}
        onKeyDown={handleKeyDown}
        autoFocus
      />
    </header>
  );
}
